//
// Created by miaomiaole on 2023/6/5.
//

#include "container.h"
#include "../algorithm/algorithm_container.h"
#include <set>
#include <string>
#include <iostream>
#include <map>
#include <algorithm>

using namespace std;

void multiset_str() {

    // 默认排序，可以重复
    multiset<string> cities{
            "Branguse", "HangKong", "BeiJing", "BeiJing"
    };
    cities.insert({
                          "Branguse", "HangKong", "BeiJing", "BeiJing"
                  });
    for (const auto &item: cities)
        cout << item << "  ";
    cout << endl;


    typedef multimap<int, string> int_string_map;

    int_string_map map1 = {
            {2, "str"},
            {3, "str3"},
            {4, "str4"},
            {5, "str5"},
            {6, "str6"},
            {6, "str6"}
    };

    for (const auto &item: map1)
        cout << " key=" << item.first << " value = " << item.second << " ";

    cout << endl;
}

typedef set<int, RuntimeCmp> IntSet;

void print_set() {

    IntSet runtimeCap = {2, 4, 5, 6, 7, 8, 9};

    for (const auto &item: runtimeCap)
        cout << "runtimeCap = " << item << endl;

    set<int> s0;
    // less排序构造器 set,map中的元素默认排序，set不能直接修改元素，只能删除后新增
    set<int, less<int>> s1;
    s1.insert(10);
    s1.insert(-10);
    s1.insert(-12);
    auto is_insert = s1.insert(40);
    cout << "insert set result first " << *is_insert.first << " result second " << is_insert.second << endl;


    cout << "s1 = (";
    for (const auto &item: s1)
        cout << item << " ";
    cout << ") " << endl;

    cout << s1.count(-40) << endl;


    // 传入的是副本（非引用）
    set<int> s2(s1);

    // 删除指定下标元素
    auto erase_s1 = s1.erase(++s1.begin());

    cout << "erase_s1 is " << *erase_s1 << endl;

    cout << "s1 = (";
    for (const auto &item: s1)
        cout << item << " ";
    cout << ") " << endl;

    cout << "s2 = (";
    for (const auto &item: s2)
        cout << item << " ";
    cout << ") " << endl;

}

// map
typedef pair<int, string> int_str_entity;
typedef map<int, string, greater<int>> int_str_map;

void print_map() {
    int_str_map m0;
    m0.insert(int_str_entity(2, "2"));
    m0.insert(int_str_entity(4, "2"));
    m0.insert(int_str_entity(6, "45"));

    int_str_map m2(m0);

    cout << "map (";
    for (const auto &item: m0)
        cout << " key = " << item.first << " value = " << item.second << " ";
    cout << ")" << endl;

    auto result = m0.emplace(2, "4");
    // 存在返回false 不存在返回true
    if (!result.second) {
        result.first->second = "4";
    }

    m0[7] = ":[]";

    cout << "map (";
    for (const auto &item: m0)
        cout << " key = " << item.first << " value = " << item.second << " ";
    cout << ")" << endl;


}

typedef map<string, int> StrIntMap;


void operator_map() {

    StrIntMap m0 = {{"stre",  1},
                    {"str43", 2}};
    m0["str"] = 2;
    m0["str2"] = 2;
    m0["str4"] = 2;
    m0["str2"] = 2;


    for_each(m0.begin(), m0.end(), [](auto &ele) {

        auto ele_prt = &ele;
        ele_prt->second *= ele_prt->second;
    });

    // 局部变量 无法更改值
    for_each(m0.begin(), m0.end(), [](pair<string, int> ele) {
        auto *prt = &ele;
        prt->second *= prt->second;
    });

    for (const auto &item: m0)
        cout << item.first << "  " << item.second << endl;


    typedef map<string, float> str_float_map;
    str_float_map m1;
    m1["str"] = 123.4f;
    m1["str2"] = 123.4f;
    m1["str3"] = 123.4f;
    m1["str4"] = 123.4f;
    m1["str5"] = 123.4f;


}

typedef set<int> set_int;

// 操作 set 集合，自动排序，使用红黑树实现
void operator_set() {

    set_int c = {1, 2, 4, 5, 6, 7, 8, 9, 0, 10, -10};

    c.insert(1);
    c.insert(3);
    c.insert(54);
    // 查询不小于val的元素

    cout << "abce:" << *(c.lower_bound(3)) << endl;
}

vector<int> ints = {1, 2, 3, 4, 5, 6, 7, 8, 8, 910, 10};

void for_each_operation() {
    for_each(ints.begin() + 2, ints.end() - 2, [](auto &&item) {
        item = move(item * 2);
    });

    cout << "ints = [";
    for (const auto &item: ints)
        cout << item << ",";

    cout << "]" << endl;

    auto count_num = count(ints.begin(), ints.end(), 10);

    cout << count_num << endl;

}
